package com.koron.system.login.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.koron.bean.query.PageQuery;
import com.koron.bean.util.ServletUtils;
import com.koron.common.core.business.configsettings.utils.ConfigInfoTool;
import com.koron.common.core.util.CodeTools;
import com.koron.common.core.util.DateAndTimeUtils;
import com.koron.common.core.util.IpUtil;
import com.koron.system.login.bean.dto.LockDto;
import com.koron.system.login.bean.po.LoginInfoPo;
import com.koron.system.login.mapper.LoginInfoMapper;
import com.koron.system.login.service.LoginInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * (LoginInfo)表服务实现类
 *
 * @author zhouj
 * @since 2021-12-06 10:13:36
 */
@Service("loginInfoService")
public class LoginInfoServiceImpl implements LoginInfoService {

    @Autowired
    LoginInfoMapper mapper;

    @Override
    public int insertOrUpdate(LoginInfoPo loginInfo) {
        return mapper.insertOrUpdate(loginInfo);
    }

    @Override
    public int insertOrUpdateBatch(List<LoginInfoPo> loginInfoList) {
        return mapper.insertOrUpdateBatch(loginInfoList);
    }

    @Override
    public int insert(LoginInfoPo loginInfo) {
        return mapper.insert(loginInfo);
    }

    @Override
    public int insertBatch(List<LoginInfoPo> loginInfoList) {
        return mapper.insertBatch(loginInfoList);
    }

    @Override
    public int update(LoginInfoPo loginInfo) {
        return mapper.update(loginInfo);
    }

    @Override
    public int deleteById(String id) {
        return mapper.deleteById(id);
    }

    @Override
    public LoginInfoPo queryById(String id) {
        return mapper.queryById(id);
    }

    @Override
    public LoginInfoPo queryByIpAndAccount(String ip, String account) {
        return mapper.queryByIpAndAccount(ip, account);
    }

    @Override
    public List<LoginInfoPo> queryList(LoginInfoPo loginInfo) {
        List<LoginInfoPo> list = mapper.queryList(loginInfo);
        return list;
    }

    @Override
    public LockDto isLock(String account) {

        LockDto lockDto = new LockDto();
        lockDto.setIsLock(false);

        String ipAddr = IpUtil.getIpAddr(ServletUtils.getRequest());
        LoginInfoPo loginInfoPo = queryByIpAndAccount(ipAddr, account);
        //判断当前时间-锁定时间 与配置时间关系
        if (Objects.isNull(loginInfoPo)) {
            lockDto.setIsLock(false);
            return lockDto;
        }
        //锁定时间 -- 更新时间({配置锁定时间内}防止校验)... fail<{配置次数}
        Integer fail = loginInfoPo.getFail();
        Date updateTime = loginInfoPo.getUpdateTime();
        long time = updateTime.getTime();
        long l = System.currentTimeMillis();
        BigDecimal bigDecimal = DateAndTimeUtils.longtimeToMin(l - time);
        if (loginInfoPo.getStatus() == 1 && bigDecimal.intValue() < getLoginConfig("lock")) {
            //锁定状态并且时间在{锁定时间}min内,返回已锁定
            lockDto.setIsLock(true);
            lockDto.setTimeLeft(getLoginConfig("lock") - bigDecimal.intValue());
            return lockDto;
        }
        return lockDto;
    }

    @Override
    public int insertOrUpdate(String account) {
        String ipAddr = IpUtil.getIpAddr(ServletUtils.getRequest());
        LoginInfoPo loginInfoPo = mapper.queryByIpAndAccount(ipAddr, account);

        Integer remainTime = 0;

        if (Objects.isNull(loginInfoPo)) {
            //新增
            loginInfoPo = new LoginInfoPo();
            loginInfoPo.setFail(1);
            loginInfoPo.setStatus(0);
            loginInfoPo.setId(CodeTools.getCode32());
            loginInfoPo.setLoginIp(ipAddr);
            loginInfoPo.setLoginName(account);
            loginInfoPo.setUpdateTime(new Date());
            insertOrUpdate(loginInfoPo);
            remainTime = getLoginConfig("fail") - loginInfoPo.getFail();
        } else {
            //更新
            Integer fail = loginInfoPo.getFail();
            fail += 1;
            //fail>{设定次数}-->设置已锁定
            loginInfoPo.setFail(fail);
            remainTime = getLoginConfig("fail") - loginInfoPo.getFail();
            if (fail >= getLoginConfig("fail")) {
                loginInfoPo.setStatus(1);
                loginInfoPo.setFail(0);
            }
            loginInfoPo.setUpdateTime(new Date());
            insertOrUpdate(loginInfoPo);
        }
        return remainTime;
    }

    @Override
    public void update(String account) {
        String ipAddr = IpUtil.getIpAddr(ServletUtils.getRequest());
        LoginInfoPo loginInfoPo = mapper.queryByIpAndAccount(ipAddr, account);

        if (Objects.isNull(loginInfoPo)) {
            //新增
            LoginInfoPo loginInfoPo1 = new LoginInfoPo();
            loginInfoPo1.setFail(0);
            loginInfoPo1.setStatus(0);
            loginInfoPo1.setId(CodeTools.getCode32());
            loginInfoPo1.setLoginIp(ipAddr);
            loginInfoPo1.setLoginName(account);
            loginInfoPo1.setUpdateTime(new Date());
            insertOrUpdate(loginInfoPo1);
        } else {
            //更新
            loginInfoPo.setLastLoginTime(new Date());
            loginInfoPo.setFail(0);
            loginInfoPo.setStatus(0);
            loginInfoPo.setUpdateTime(new Date());
            insertOrUpdate(loginInfoPo);
        }
    }

    @Override
    public PageInfo queryPageList(LoginInfoPo loginInfo, PageQuery pageQuery) {
        PageHelper.startPage(pageQuery.getPage(), pageQuery.getPageSize(), pageQuery.getOrderBy());
        List<LoginInfoPo> list = mapper.queryList(loginInfo);
        return new PageInfo(list);
    }

    Integer getLoginConfig(String key) {
        Map<String, String> config = getConfig();
        return Integer.parseInt(config.getOrDefault(key, "5"));
    }

    Map<String, String> getConfig() {
        return ConfigInfoTool.getConfigByCode("system", "system_login_config");
    }

}
